package RMIClient;

import RMIClient.gui.RMIClientGUI;

import util.observer.local.LocalObservable;
import java.util.Observer;
import java.rmi.RemoteException;

import java.util.List;

import eventReservationServer.EventRMIDTO;
import eventReservationServer.IReservationEventServer;
import eventReservationServer.loginGateway.ValidationException;

public class EventController
{
	// Some data you may need
	// Feel free to add what you need
	private IReservationEventServer server;
	private LocalObservable observable;
	private EventRemoteObserver observer;
	

	// CLIENT SESSION STATE - state management field.
	private UserRMIDTO user = null;

	/**
	 * Creates a new instance of ReservationController
	 * 
	 * @throws RemoteException
	 */
	public EventController(String[] args) throws RemoteException
	{
		observable = new LocalObservable();
		
		// Obtenemos referencia al servicio que nos proporciona IReservationEventServer (patron Service Locator)
		server = new RMIServiceLocator().getService();
		
		// Creamos el observador remoto que es el que recibira invocaciones desde el servidor
		// Le enviamos el server que es el que le enviara informacion remota
		observer = new EventRemoteObserver(server, this);
		
		new RMIClientGUI(this);

	}

	// --------------- System Events - Remote Method Invocation --------
	// TO BE COMPLETELY PROGRAMMED BY THE STUDENTS - 1st Assignment

	public UserRMIDTO login(String username, String pass) throws ValidationException
	{		
		try
		{
			user = server.login(username, pass);
			
			System.out.println("* Message coming from the server: '" + user.toString() + "'");
			
			// Si me devuelve el user es que el login ha tenido exito y por tanto a�ado un nuevo observador remoto al servidor
			if (user != null)
			{
				server.addRemoteObserver(observer);
			}
		} 
		catch (RemoteException e)
		{
			System.err.println("Login exception: " + e.getMessage());
			e.printStackTrace();
		}
		
		return user;
	}

	public List<EventRMIDTO> getEvents() 
	{
		List<EventRMIDTO> events = null;
		
		try
		{
			events = server.getEvents();
		} 
		catch (RemoteException e)
		{
			System.err.println("GetEvents exception: " + e.getMessage());
			e.printStackTrace();
		}

		return events;
	}

	public void reservePlace(String serverName, String eventName) 
	{		
		try
		{
			server.reservePlace(user.getUsername(), serverName, eventName);
		} 
		catch (Exception e)
		{
			System.err.println("ReservePlace exception: " + e.getMessage());
			e.printStackTrace();
		}
	}

	// -------- Remote Observer Notification ---------------
	public void updateEvent(EventRMIDTO e)
	{
		// propagate the changed Event so that the GUI can update the Event details
		// Notificamos a todos los observers (clientes) el cambio realizado por otro cliente
		this.notifyLocalObservers(e);

	}

	// ------------------ End of Remote Observer Notification --------
	public void exit() throws RemoteException
	{
		observer.stop();
		System.exit(0);
	}

	// ---------------------- Local Observable ---------------------------
	public void addLocalObserver(Observer observer)
	{
		observable.addObserver(observer);
	}

	public void deleteLocalObserver(Observer observer)
	{
		observable.deleteObserver(observer);
	}

	public void notifyLocalObservers(Object arg)
	{
		observable.setChanged();
		observable.notifyObservers(arg);
	}

	/**
	 * @param args
	 *            the command line arguments
	 * @throws RemoteException
	 */
	public static void main(String[] args) throws RemoteException
	{
		new EventController(args);
	}
}
